home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Aminet 4
/
Aminet 4 - November 1994.iso
/
aminet
/
comm
/
net
/
dnet_src.lha
/
dnet
/
amiga
/
server
/
sgcopy.c
< prev
next >
Wrap
C/C++ Source or Header
|
1989-11-27
|
8KB
|
400 lines
/*
* SGCOPY.C V1.1
*
* DNET (c)Copyright 1988, Matthew Dillon, All Rights Reserved.
*
* GET-COPY SERVER (NEW COPY SERVER)
*
* The current version only accepts one connection at a time. This server
* will send requested files to the remote machine.
*
* length in 68000 longword format.
*
* ACCESS RESTRICTIONS:
*
* Remote access restrictions are according to DNET_GROUP or DNET_READ
*
* DNET_READ >= 9 Full Access
* DNET_READ < 9 According to comment field (AC=n) or group acc.
* (GR=n) matches DNET_GROUP)
*
* When searching for access rights, the comment field of the file/dir
* requested is checked first. If empty, the parent dir is checked.
* This continues (parent diring) until root is found or a comment
* field with access info in it.
*/
#include "defs.h"
typedef struct {
char Cmd;
char Str[64];
long Val;
} HDR;
extern int Enable_Abort;
char Buf[8192];
void *Chan;
void SGCopy ARGS((void));
int PutObject ARGS((char *));
int PutDir ARGS((char *, int));
int PutFile ARGS((char *, int));
int WriteHeader ARGS((char, char *, long));
int ReadHeader ARGS((HDR *));
int
brk()
{
return(0);
}
void
#ifdef LATTICE
_main(str)
#else
_main(len,str)
#endif
char *str;
{
struct MsgPort *port;
PROC *myproc = (PROC *)FindTask(NULL);
long savedir;
long mask, rmask;
onbreak(brk);
if (strncmp(str, "__dnet", 6) != 0) {
Version("SGCopy", VERSION, SGCOPY_VERSION);
_exit(0);
}
port = DListen(PORT_GFILECOPY);
WaitPort(&myproc->pr_MsgPort);
ReplyMsg(GetMsg(&myproc->pr_MsgPort));
savedir = Lock("", SHARED_LOCK); /* duplicate current dir */
if (!savedir) {
DUnListen(port);
_exit(1);
}
savedir = CurrentDir(savedir); /* CD dup, returns original */
mask = SIGBREAKF_CTRL_C|(1 << port->mp_SigBit);
for (;;) {
long dupdir = DupLock(myproc->pr_CurrentDir);
rmask = Wait(mask);
if (rmask & SIGBREAKF_CTRL_C) {
UnLock(CurrentDir(dupdir));
break;
}
while (Chan = DAccept(port)) {
SGCopy();
DClose(Chan);
}
UnLock(CurrentDir(dupdir));
}
UnLock(CurrentDir(savedir)); /* restore original */
DUnListen(port);
}
void
SGCopy()
{
short error;
static HDR Hdr;
error = WriteHeader('H', "Hello, GCopy server V1.30", 0);
if (error)
return;
switch(ReadHeader(&Hdr)) {
case -1:
return;
case 'H':
break;
}
while (!error) {
switch(ReadHeader(&Hdr)) {
case 'G':
error = PutObject(Hdr.Str);
break;
case 'E':
goto done;
case 'P': /* put-files, not implemented */
default:
error = 1;
break;
}
}
done:
;
}
int
PutObject(str)
char *str;
{
long lock;
FIB *fib = malloc(sizeof(FIB));
short error = 0;
short access = GetEnvVal(DNET_READ);
short group = GetEnvVal(DNET_GROUP);
mountrequest(0);
lock = Lock(str, SHARED_LOCK);
mountrequest(1);
if (lock == NULL || !Examine(lock, fib)) { /* unable to find it! */
error = WriteHeader('N', "Unable to find object", 0);
goto done;
}
/*
* Determine Access rights
*
* If the file/dir or any parent dir has AC > your_ac, access is
* denied. If the file/dir and all parent dirs have neither an ACcess
* or GRoup entry, access is denied. If a group entry is found that
* matches your group, access is allowed (unless an AC is found > your_ac)
*
* If your_ac is >= 9, no access checking of parent directories is
* done at all. However, access checking of downloaded files will
* be done, and any AC values > your_ac will be disalloweds.
*/
if (access < 9) { /* must check comment/access */
short ok = 0;
long lock2 = DupLock(lock);
long tmp;
for (;;) {
short ac = 0;
while (ac >= 0) { /* check groups */
short idx = 0;
ac = ExtractFieldVal(fib->fib_Comment, FS_GROUP, &idx);
if (ac >= 0 && ac == group) {
ok = 1;
break;
}
}
ac = ExtractFieldVal(fib->fib_Comment, FS_ACCESS, NULL);
if (ac >= 0) { /* valid access field */
if (ac <= access) { /* access ok */
ok = 1;
} else { /* access not ok */
ok = 0;
break;
}
}
if (tmp = ParentDir(lock2)) { /* check the par.dir */
UnLock(lock2);
lock2 = tmp;
fib->fib_Comment[0] = 0;
Examine(lock2, fib);
continue;
}
break;
}
UnLock(lock2);
if (!ok) {
error = WriteHeader('N', "Access Violation", 0);
goto done;
}
}
Examine(lock, fib);
UnLock(lock);
lock = NULL;
if (fib->fib_DirEntryType > 0) {
error = PutDir(str, access);
} else {
error = PutFile(str, access);
}
done:
if (lock)
UnLock(lock);
free(fib);
return((int)error);
}
int
PutDir(name, access)
char *name;
int access;
{
long lock = Lock(name, SHARED_LOCK);
FIB *fib = malloc(sizeof(FIB));
static HDR Hdr;
short error = 0;
short ac;
if (!lock || !Examine(lock, fib)) {
WriteHeader('N', "Possible Disk Error", 0);
error = 1;
goto done;
}
ac = ExtractFieldVal(fib->fib_Comment, FS_ACCESS, NULL);
if (ac >= 0 && ac > access) {
error = WriteHeader('S', fib->fib_FileName, 0);
goto done;
}
if (error = WriteHeader('D', fib->fib_FileName, 0))
goto done;
switch(ReadHeader(&Hdr)) {
case 'Y':
break;
case 'S':
goto done;
case 'N':
error = 1;
break;
default:
error = 1;
break;
}
if (error)
goto done;
while (ExNext(lock, fib)) { /* try to give him the files */
if (fib->fib_DirEntryType > 0) {
long oldlock = CurrentDir(lock);
error = PutDir(fib->fib_FileName, access);
CurrentDir(oldlock);
if (error)
break;
} else {
long oldlock = CurrentDir(lock);
error = PutFile(fib->fib_FileName, access);
CurrentDir(oldlock);
if (error)
break;
}
}
if (!error)
WriteHeader('E', "Possible Disk Error", 0);
done:
free(fib);
if (lock)
UnLock(lock);
return((int)error);
}
int
PutFile(name, access)
char *name;
int access;
{
long lock = Lock(name, SHARED_LOCK);
long fh = NULL;
FIB *fib = malloc(sizeof(FIB));
static HDR Hdr;
long len;
short error = 0;
short ac;
if (!lock || !Examine(lock, fib)) {
WriteHeader('N', "Possible Disk Error", 0);
error = 1;
goto done;
}
ac = ExtractFieldVal(fib->fib_Comment, FS_ACCESS, NULL);
if (ac >= 0 && ac > access) {
error = WriteHeader('S', fib->fib_FileName, 0);
goto done;
}
fh = Open(name, 1005);
if (fh == NULL) /* don't do anything if unable to open it */
goto done;
Seek(fh, 0L, 1);
len = Seek(fh, 0L, 0);
if (error = WriteHeader('F', fib->fib_FileName, len))
goto done;
switch(ReadHeader(&Hdr)) {
case 'Y':
Seek(fh, Hdr.Val, -1); /* start pos. */
len -= Hdr.Val;
if (len < 0)
len = 0;
break;
case 'S':
goto done;
case 'N':
error = 1;
break;
default:
error = 1;
break;
}
if (error)
goto done;
while (len) {
long n = (len > sizeof(Buf)) ? sizeof(Buf) : len;
if (Read(fh, Buf, n) != n) { /* read failed! */
error = 10;
goto done;
}
if (DWrite(Chan, Buf, n) != n) {
error = 10;
goto done;
}
len -= n;
}
done:
free(fib);
if (fh)
Close(fh);
if (lock)
UnLock(lock);
return((int)error);
}
int
WriteHeader(c, str, len)
char c;
char *str;
long len;
{
ubyte sl;
if (str == NULL)
str = "";
sl = strlen(str);
if (DWrite(Chan, &c, 1) < 0)
return(1);
if (DWrite(Chan, &sl,1) < 0)
return(1);
if (DWrite(Chan, str, sl) != sl)
return(1);
if (DWrite(Chan, &len, 4) != 4)
return(1);
return(0);
}
int
ReadHeader(hdr)
HDR *hdr;
{
ubyte sl;
ubyte cmd;
hdr->Cmd = -1;
if (DRead(Chan, &cmd, 1) != 1)
return(-1);
if (DRead(Chan, &sl, 1) != 1)
return(-1);
if (sl >= sizeof(hdr->Str)) {
return(-1);
}
if (DRead(Chan, hdr->Str, sl) != sl)
return(-1);
hdr->Str[sl] = 0;
if (DRead(Chan, &hdr->Val, 4) != 4)
return(-1);
hdr->Cmd = cmd;
return((int)hdr->Cmd);
}